package com.kanas.webak.config.service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.inject.Singleton;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.kanas.framework.business.BusinessException;
import com.kanas.framework.util.IteratorUtils;
import com.kanas.webak.config.domain.Sequence;
import com.kanas.webak.config.repository.SequenceRepository;

@Service("com.kanas.webak.config.service.sequenceservice")
@Singleton
public class SequenceServiceImpl implements SequenceService{
	
	@Autowired
	private SequenceRepository sequenceRepository;
	
	@Override
	@Transactional
	public Sequence addNew(Sequence sq) throws Exception {
		Sequence it = sequenceRepository.findByCode(sq.getCode());
		if(it!=null)throw BusinessException.DATA_DUPLICATION;
		sequenceRepository.save(sq);
		return sq;
	}
	
	@Override
	@Transactional
	public Sequence update(Sequence se) throws Exception {
		Sequence seq = sequenceRepository.findOne(se.getId());
		if(seq==null)throw BusinessException.DATA_NOT_FOUND;
		Sequence seqtmp = sequenceRepository.findByCode(se.getCode());
		if(seqtmp!=null){
			if(!seqtmp.getId().equals(se.getId())) throw BusinessException.DATA_DUPLICATION;
		}
		seq.setLabel(se.getLabel());
		seq.setCode(se.getCode());
		seq.setValue(se.getValue());
		seq.setLastUpdate(new Date());
		seq.setResetInterval(se.getResetInterval());
		sequenceRepository.save(seq);
		return seq;
	}

	@Override
	@Transactional
	public void remove(String id) throws Exception {
		this.sequenceRepository.delete(id);
	}
	
	@Override
	@Transactional
	public Sequence findOne(String id) {
		Sequence dt = sequenceRepository.findOne(id);
		return dt;
	}
	
	@Override
	@Transactional
	public List<Sequence> findAll() {
		return IteratorUtils.asList(sequenceRepository.findAll().iterator());
	}

	/**
	 * Pattern example: 'PRE'yyyyMMdd'MID'{000}'SUR'
	 */
	@Override
	@Transactional
	public String fetchSeed(String pattern,String code) throws Exception{
		Sequence seq = this.sequenceRepository.findByCode(code);
		if(null==seq)throw BusinessException.DATA_NOT_FOUND;
		Long seed = seq.increase();
		this.sequenceRepository.save(seq);
		String temp;
		SimpleDateFormat df1 = new SimpleDateFormat(pattern);
		temp = df1.format(new Date());
		temp = ("'"+temp.replaceAll("\\{", "'").replaceAll("\\}", "'")+"'").replaceAll("''", "");
        DecimalFormat df2 = new DecimalFormat(temp);
        return df2.format(seed);
	}

	@Override
	@Transactional
	public void reset() {
		this.sequenceRepository.reset(new Date(), Sequence.ResetIntervalType.DAY.toString());
		if(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)==1)
			this.sequenceRepository.reset(new Date(), Sequence.ResetIntervalType.MONTH.toString());
		if(Calendar.getInstance().get(Calendar.DAY_OF_YEAR)==1)
			this.sequenceRepository.reset(new Date(), Sequence.ResetIntervalType.YEAR.toString());
	}
	
	public SequenceRepository getSequenceRepository() {
		return sequenceRepository;
	}

	public void setSequenceRepository(SequenceRepository sequenceRepository) {
		this.sequenceRepository = sequenceRepository;
	}

}
